/*******************************************************************
* ++
* Author        :	ThienTN
* Description   :	NhanVien.h in project HRManagement
* 
* Mod. History  :	25/07/2012 - ThienTN
*
* --
*******************************************************************/

#include <fstream>
#include "Employee.h" 
#include "Utility.h"

CEmployee::CEmployee(void)
{
	m_wszID = "";
	m_wszName = "";
	m_birthDay.m_nDate = 0;
	m_birthDay.m_nMonth = 0;
	m_birthDay.m_nYear = 0;
	m_wszAddress = "";
	m_nSalary = 2000;
}

CEmployee::~CEmployee(void)
{
}

/*
 * Check validate of input (birthday)
 * param: s Employee variable
 */
bool CheckBirthday(CEmployee *pEmployee)
{
	bool temp = true;
	// Check year valid
	if (pEmployee->m_birthDay.m_nYear < 0 || pEmployee->m_birthDay.m_nYear > 2012)
	{
		printf("Year is not available!");
		return false;
	}
	else
	{
		// Check month valid
		if (pEmployee->m_birthDay.m_nMonth < 1 || pEmployee->m_birthDay.m_nMonth >12)
		{
			printf("Month is not available!");
			return false;
		} 
		else
		{
			if (pEmployee->m_birthDay.m_nMonth == 1 || pEmployee->m_birthDay.m_nMonth == 3 || pEmployee->m_birthDay.m_nMonth == 5 || pEmployee->m_birthDay.m_nMonth == 7 || pEmployee->m_birthDay.m_nMonth == 8 || pEmployee->m_birthDay.m_nMonth == 10 || pEmployee->m_birthDay.m_nMonth == 12)
			{
				// Check month has 31 days.
				if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 31)
				{
					printf("Day is not available!");
					return false;
				}
			} 
			else
			{
				if (pEmployee->m_birthDay.m_nMonth == 4 || pEmployee->m_birthDay.m_nMonth == 6 || pEmployee->m_birthDay.m_nMonth == 9 || pEmployee->m_birthDay.m_nMonth == 11)
				{
					// Check month has 30 days.
					if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 30)
					{
						printf("Day is not available!");
						return false;
					}
				} 
				else
				{
					if (pEmployee->m_birthDay.m_nMonth == 2)
					{
						if ((pEmployee->m_birthDay.m_nDate % 4 == 0 && pEmployee->m_birthDay.m_nDate % 100 != 0) || pEmployee->m_birthDay.m_nDate % 400 == 0)
						{
							// Check month has 29 days (Leap year).
							if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 29)
							{
								printf("Day is not available!");
								return false;
							}
						} 
						else
						{
							// Check month has 28 days (Leap year).
							if (pEmployee->m_birthDay.m_nDate < 1 || pEmployee->m_birthDay.m_nDate > 28)
							{
								printf("Day is not available!");
								return false;
							}
						}
					}
				}
			}
		}
	}
	return true;
}

void CEmployee::InputEmployee(CEmployee *pEmployee)
{
	//Input ID
	cout << "\tInput ID: ";
	cin >> pEmployee->m_wszID;

	// Input employee's name
	cout << "\tInput name: ";
	cin >> pEmployee->m_wszName;

	// Input employee's birthday
	cout << "\tInput Birthday(dd mm yy): ";
	cin >> (pEmployee->m_birthDay.m_nDate);
	cin >> (pEmployee->m_birthDay.m_nMonth);
	cin >> (pEmployee->m_birthDay.m_nYear);
	while (!CheckBirthday(pEmployee))
	{
		cout << "\tInput Birthday(dd mm yy): ";
		cin >> (pEmployee->m_birthDay.m_nDate);
		cin >> (pEmployee->m_birthDay.m_nMonth);
		cin >> (pEmployee->m_birthDay.m_nYear);
	}

	// Input employee's grad school
	cout << "\tInput Address: ";
	cin >> pEmployee->m_wszAddress;
	
	// Input employee's gradType
	cout << "\tInput Salary: ";
	cin >> pEmployee->m_nSalary;

}

void CEmployee::Display(CEmployee *pEmployee)
{
	cout << "ID       : " << pEmployee->m_wszID <<endl;
	cout << "Name     : " << pEmployee->m_wszName <<endl;
	cout << "Birthday : " << pEmployee->m_birthDay.m_nDate << "-" << pEmployee->m_birthDay.m_nMonth << "-" << pEmployee->m_birthDay.m_nYear <<endl;
	cout << "Address  : " << pEmployee->m_wszAddress <<endl;
	cout << "Salary   : " << pEmployee->m_nSalary << "$" <<endl;
	cout << endl;

}
/*
 * Display list
 * param: l list student 
 */
void CEmployee::OutputEmployee(List *pList)
{
	Node *pNode;
	pNode = pList->pHead;
	while (pNode != NULL)
	{
		Display(pNode->info);
		pNode = pNode->pNext;
	}
}

/*
 * Swap position of 2 student
 * param: a Student pointer
 * param: b Student pointer
 */
void Swap(CEmployee *a, CEmployee *b)
{
	CEmployee c;
	c = *a;
	*a = *b;
	*b = c;
}


void CEmployee::AutoInputEmployee( List *pList )
{
	Node *pNode;
	CEmployee *pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0001";
	pEmployee->m_wszName = "Tran Ngoc Thien";
	pEmployee->m_birthDay.m_nDate = 31;
	pEmployee->m_birthDay.m_nMonth = 3;
	pEmployee->m_birthDay.m_nYear = 1990;
	pEmployee->m_wszAddress = "Daklak";
	pEmployee->m_nSalary = 1000;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0002";
	pEmployee->m_wszName = "Pham Trung Nguyen";
	pEmployee->m_birthDay.m_nDate = 29;
	pEmployee->m_birthDay.m_nMonth = 12;
	pEmployee->m_birthDay.m_nYear = 1990;
	pEmployee->m_wszAddress = "Quang Binh";
	pEmployee->m_nSalary = 1200;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0003";
	pEmployee->m_wszName = "Nguyen Minh Tan";
	pEmployee->m_birthDay.m_nDate = 1;
	pEmployee->m_birthDay.m_nMonth = 3;
	pEmployee->m_birthDay.m_nYear = 1989;
	pEmployee->m_wszAddress = "Dong Nai";
	pEmployee->m_nSalary = 1500;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0004";
	pEmployee->m_wszName = "Nguyen Tuan Vu";
	pEmployee->m_birthDay.m_nDate = 1;
	pEmployee->m_birthDay.m_nMonth = 1;
	pEmployee->m_birthDay.m_nYear = 1992;
	pEmployee->m_wszAddress = "Ha Noi";
	pEmployee->m_nSalary = 800;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0005";
	pEmployee->m_wszName = "Le Ngoc Tuan";
	pEmployee->m_birthDay.m_nDate = 15;
	pEmployee->m_birthDay.m_nMonth = 8;
	pEmployee->m_birthDay.m_nYear = 1988;
	pEmployee->m_wszAddress = "Ha Noi";
	pEmployee->m_nSalary = 1100;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0006";
	pEmployee->m_wszName = "Nguyen Cong Tan";
	pEmployee->m_birthDay.m_nDate = 20;
	pEmployee->m_birthDay.m_nMonth = 9;
	pEmployee->m_birthDay.m_nYear = 1994;
	pEmployee->m_wszAddress = "Vung Tau";
	pEmployee->m_nSalary = 900;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0007";
	pEmployee->m_wszName = "Cap Van Vu";
	pEmployee->m_birthDay.m_nDate = 13;
	pEmployee->m_birthDay.m_nMonth = 3;
	pEmployee->m_birthDay.m_nYear = 1990;
	pEmployee->m_wszAddress = "ha noi";
	pEmployee->m_nSalary = 1100;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0008";
	pEmployee->m_wszName = "Nguyen Vu Hoang";
	pEmployee->m_birthDay.m_nDate = 23;
	pEmployee->m_birthDay.m_nMonth = 3;
	pEmployee->m_birthDay.m_nYear = 1990;
	pEmployee->m_wszAddress = "Vinh Long";
	pEmployee->m_nSalary = 1000;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0009";
	pEmployee->m_wszName = "Pham Thi Ha";
	pEmployee->m_birthDay.m_nDate = 30;
	pEmployee->m_birthDay.m_nMonth = 12;
	pEmployee->m_birthDay.m_nYear = 1989;
	pEmployee->m_wszAddress = "Ha noi";
	pEmployee->m_nSalary = 1000;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

	pEmployee = new CEmployee;
	pEmployee->m_wszID = "EMP0010";
	pEmployee->m_wszName = "Nguyen Trung Luu";
	pEmployee->m_birthDay.m_nDate = 20;
	pEmployee->m_birthDay.m_nMonth = 4;
	pEmployee->m_birthDay.m_nYear = 1990;
	pEmployee->m_wszAddress = "Daklak";
	pEmployee->m_nSalary = 600;
	pNode = CreateNode(pEmployee);
	AddHead(pList, pNode);

}

/*
 * Write to file
 * param: s Student array
 * param: n Student amount
 */
void CEmployee::WriteEmployee(ofstream &f)
{
	f << this->m_wszID << endl;
	f << this->m_wszName << endl;
	f << this->m_birthDay.m_nDate << endl;
	f << this->m_birthDay.m_nMonth << endl;
	f << this->m_birthDay.m_nYear << endl;
	f << this->m_wszAddress << endl;
	f << this->m_nSalary << endl;
}
/*
 * Soft list student belong to birthday
 * param: arr Student array
 * param: n Student amount
 */
bool CEmployee::CompareBirthday( CEmployee *a, CEmployee *b )
{
	if (a->m_birthDay.m_nYear > b->m_birthDay.m_nYear)
	{
		return true;
	}
	else
	{
		if(a->m_birthDay.m_nYear == b->m_birthDay.m_nYear)
		{
			if (a->m_birthDay.m_nMonth > b->m_birthDay.m_nMonth)
			{
				return true;
			}
			else
			{
				if (a->m_birthDay.m_nMonth == b->m_birthDay.m_nMonth)
				{
					if (a->m_birthDay.m_nDate > b->m_birthDay.m_nDate)
					{
						return true;
					} 
				}
			}
		}
	}
	return false;
}

/*
 * Quick sort list student by birthday
 * param: l list student 
 */
void CEmployee::QuickSortBirthday( List *pList )
{
	Node *pNode, *pNodeX;
	List l1, l2;
	if (pList->pHead == pList->pTail) return;
	CreateList(&l1);
	CreateList(&l2);
	pNodeX = pList->pHead;
	pList->pHead = pNodeX->pNext;

	while (pList->pHead != NULL)
	{
		pNode=pList->pHead;
		pList->pHead = pNode->pNext;
		pNode->pNext = NULL;
		if (CompareBirthday(pNodeX->info, pNode->info))
		{
			AddHead(&l1,pNode);
		}
		else
			AddHead(&l2,pNode);
	}
	QuickSortBirthday(&l1);
	QuickSortBirthday(&l2);
	if (l1.pHead != NULL)
	{
		pList->pHead = l1.pHead;
		l1.pTail->pNext = pNodeX;
	}

	else
		pList->pHead = pNodeX;
	pNodeX->pNext = l2.pHead;
	if (l2.pHead != NULL)
		pList->pTail = l2.pTail;
	else
		pList->pTail = pNodeX;
}

void CEmployee::QuickSortSalary( List *pList )
{
	Node *pNode, *pNodeX;
	List l1, l2;
	if (pList->pHead == pList->pTail) return;
	CreateList(&l1);
	CreateList(&l2);
	pNodeX = pList->pHead;
	pList->pHead = pNodeX->pNext;

	while (pList->pHead != NULL)
	{
		pNode=pList->pHead;
		pList->pHead = pNode->pNext;
		pNode->pNext = NULL;
		if (pNode->info->m_nSalary <= pNodeX->info->m_nSalary)
		{
			AddHead(&l1,pNode);
		}
		else
			AddHead(&l2,pNode);
	}
	QuickSortSalary(&l1);
	QuickSortSalary(&l2);
	if (l1.pHead != NULL)
	{
		pList->pHead = l1.pHead;
		l1.pTail->pNext = pNodeX;
	}

	else
		pList->pHead = pNodeX;
	pNodeX->pNext = l2.pHead;
	if (l2.pHead != NULL)
		pList->pTail = l2.pTail;
	else
		pList->pTail = pNodeX;
}

void CEmployee::RemoveEmployee(List *pList)
{
	Node *p, *q;
	string x;
	p = pList->pHead;
	q = NULL; // Keep tracking previous element of p

	while (p != NULL)
	{
		x = p->info->m_wszAddress;
		for (int i = 0; i < x.length(); i++)
		{
			x[i] = towlower(x[i]);
		}
		if (x.compare("ha noi") !=  0)
		{
			Node *temp;
			temp = p;
			// p is pHead
			if (p == pList->pHead)
			{
				// List has 1 element
				if (p->pNext == NULL)
				{
					pList->pHead = NULL;
					pList->pTail = NULL;
				}
				else
				{
					pList->pHead = p->pNext;
				}
			}
			else
			{
				// p is last element
				if (p->pNext == NULL)
				{
					q->pNext = NULL;
					pList->pTail = q;
				}
				else
				{
					q->pNext = p->pNext;
				}
			}
			p = p->pNext;
			delete temp;
		}
		else
		{
			q = p;
			p = p->pNext;
		}
	};
}
